package com.imageim.yimirror.common.util;

import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.iflytek.cloud.RequestListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvent;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.FileDownloadListener;
import com.iflytek.cloud.util.ResourceUtil;
import com.imageim.yimirror.R;
import com.imageim.yimirror.base.BaseApplication;
import com.imageim.yimirror.common.ui.SceneManager;
import com.martin.ads.omoshiroilib.ui.CameraPreviewActivity;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 * Created by Yuaihen on 2017/12/25.
 * 讯飞语音唤醒工具类
 */

public class WakeUpUtil {

    private static final String TAG = "WakeUpUtil";

    /************讯飞语音唤醒****************/
    // 语音唤醒对象
    private static VoiceWakeuper mIvw;
    // 唤醒结果内容
    private static String resultString;

    // 设置门限值 ： 门限值越低越容易被唤醒
    private final static int MAX = 60;
    private final static int MIN = -20;
    private static int curThresh = 0;
    private String threshStr = "门限值：";
    private static String keep_alive = "1";
    //闭环优化 0关闭 1开启
    private static String ivwNetMode = "1";

    /************讯飞语音唤醒****************/


    public static void initWakeUp() {
        //创建讯飞语音唤醒对象
        if (mIvw == null) {
            mIvw = VoiceWakeuper.createWakeuper(BaseApplication.getContext(), null);
            mIvw = VoiceWakeuper.getWakeuper();
            //非空判断，防止因空指针使程序崩溃
            if (mIvw != null) {
                resultString = "";
                // 清空参数
                mIvw.setParameter(SpeechConstant.PARAMS, null);
                // 唤醒门限值，根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入  TODO 增加唤醒词需要设置
                mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
                // 设置唤醒模式
                mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
                // 设置持续进行唤醒
                mIvw.setParameter(SpeechConstant.KEEP_ALIVE, keep_alive);
                // 设置闭环优化网络模式
                mIvw.setParameter(SpeechConstant.IVW_NET_MODE, ivwNetMode);
                // 设置唤醒资源路径
                mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
                // 设置唤醒录音保存路径，保存最近一分钟的音频
                mIvw.setParameter(SpeechConstant.IVW_AUDIO_PATH, Environment.getExternalStorageDirectory().getPath() + "/msc/ivw.wav");
                mIvw.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
                // 如有需要，设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节
                //            mIvw.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" );
                queryResource();

                // 启动唤醒
                mIvw.startListening(mWakeuperListener);
                Log.d(TAG, "语音唤醒初始化完成");
                //                Toast.makeText(BaseApplication.getContext(), "唤醒初始化完成", Toast.LENGTH_SHORT).toast();
            } else {
                //                Toast.makeText(BaseApplication.getContext(), "唤醒未初始化", Toast.LENGTH_SHORT).toast();
            }
        }
    }

    private static String getResource() {
        final String resPath = ResourceUtil.generateResourcePath(BaseApplication.getContext(), ResourceUtil.RESOURCE_TYPE.assets, "ivw/" + BaseApplication.getContext().getString(R.string.ifly_app_id) + ".jet");
        Log.d(TAG, "resPath: " + resPath);
        return resPath;
    }

    static String resultId = "";
    private static WakeuperListener mWakeuperListener = new WakeuperListener() {

        @Override
        public void onResult(WakeuperResult result) {
            Log.d(TAG, "onResult");
            if (!"1".equalsIgnoreCase(keep_alive)) {
                Toast.makeText(BaseApplication.getContext(), "keep_alive=0", Toast.LENGTH_SHORT).show();
            }
            try {
                String text = result.getResultString();
                JSONObject object;
                object = new JSONObject(text);
                StringBuffer buffer = new StringBuffer();
                buffer.append("【RAW】 " + text);
                buffer.append("\n");
                buffer.append("【操作类型】" + object.optString("sst"));
                buffer.append("\n");
                buffer.append("【唤醒词id】" + object.optString("id"));
                buffer.append("\n");
                resultId = object.optString("id");
                buffer.append("【得分】" + object.optString("score"));
                buffer.append("\n");
                buffer.append("【前端点】" + object.optString("bos"));
                buffer.append("\n");
                buffer.append("【尾端点】" + object.optString("eos"));
                resultString = buffer.toString();
                Log.d(TAG, "onResult: " + resultString);
            } catch (JSONException e) {
                resultString = "结果解析出错";
                e.printStackTrace();
            }

            //根据获取到的ID来执行操作  TODO 增加唤醒词
            switch (resultId) {
                case "0":   //我要拍照
                    SceneManager.toScene(BaseApplication.getContext(), CameraPreviewActivity.class, null);
                    break;
                case "1":
                    break;
                case "2":
                    break;
                case "3":
                    break;
                case "4":
                    break;
                default:
            }
        }

        @Override
        public void onError(SpeechError error) {
            Log.d(TAG, "onError: " + error.getErrorDescription());
        }

        @Override
        public void onBeginOfSpeech() {
            Log.d(TAG, "onBeginOfSpeech: 开始说话");
        }

        @Override
        public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
            switch (eventType) {
                // EVENT_RECORD_DATA 事件仅在 NOTIFY_RECORD_DATA 参数值为 真 时返回
                case SpeechEvent.EVENT_RECORD_DATA:
                    final byte[] audio = obj.getByteArray(SpeechEvent.KEY_EVENT_RECORD_DATA);
                    Log.i(TAG, "ivw audio length: " + audio.length);
                    break;
                default:
            }
        }

        @Override
        public void onVolumeChanged(int volume) {

        }
    };

    //-----------------------------闭环优化-------------------------------------------

    /**
     * 可以每隔一段时间后查询是否有资源更新，如每周，每月，当有资源更新时，下载新的资源以替换当前使用的资源.
     * 查询闭环优化唤醒资源
     * 请在闭环优化网络模式1或者模式2使用
     */
    public static void queryResource() {
        //        int ret = mIvw.queryResource(getResource(), requestListener);
        //        Log.d(TAG, "updateResource ret:" + ret);
    }

    /**
     * 下载闭环优化唤醒资源
     * 请在闭环优化网络模式1或者模式2使用
     *
     * @param uri 查询请求返回下载链接
     * @param md5 查询请求返回资源md5
     */
    public static void downloadResource(String uri, String md5) {
        if (TextUtils.isEmpty(uri)) {
            return;
        }
        String path = Environment
                .getExternalStorageDirectory().getAbsolutePath()
                + "/msc/res/" + BaseApplication.getContext().getString(R.string.ifly_app_id) + ".jet";
        mIvw.downloadResource(uri, path, md5, downloadListener);
    }

    // 查询资源请求回调监听
    private static RequestListener requestListener = new RequestListener() {
        @Override
        public void onEvent(int eventType, Bundle params) {
            // 以下代码用于获取查询会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                Log.d(TAG, "sid:" + params.getString(SpeechEvent.KEY_EVENT_SESSION_ID));
            }
        }

        @Override
        public void onCompleted(SpeechError error) {
            if (error != null) {
                Log.d(TAG, "error:" + error.getErrorCode());
            }
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            try {
                String resultInfo = new String(buffer, "utf-8");
                Log.d(TAG, "resultInfo:" + resultInfo);

                JSONTokener tokener = new JSONTokener(resultInfo);
                JSONObject object = new JSONObject(tokener);

                int ret = object.getInt("ret");
                if (ret == 0) {
                    String uri = object.getString("dlurl");
                    String md5 = object.getString("md5");
                    Log.d(TAG, "uri:" + uri);
                    Log.d(TAG, "md5:" + md5);
                    //下载资源，下载状态通过 wakeListener 获取
                    downloadResource(uri, md5);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    // 下载资源回调监听
    private static FileDownloadListener downloadListener = new FileDownloadListener() {
        @Override
        public void onStart() {
            // 下载启动回调
            Log.d(TAG, "download onStart");
        }

        @Override
        public void onProgress(int percent) {
            // 下载进度信息
            Log.d(TAG, "download onProgress,percent:" + percent);
        }

        @Override
        public void onCompleted(String filePath, SpeechError error) {
            // 下载完成回调
            if (error != null) {
                Log.d(TAG, "error:" + error.getErrorCode());
            } else {
                Log.d(TAG, "download onFinish,filePath:" + filePath);
            }
        }
    };
    //---------------------------------------闭环优化-------------------------------------------


    // 销毁合成对象
    public static void cancelWakeUp() {
        if (mIvw != null) {
            mIvw.destroy();
            mIvw = null;
        }
    }
}
